package geo.com.geosdkdemo.view.activity;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.geo.parse.GnssRefStationData;
import com.geo.parse.GnssSateInfo;
import com.geo.parse.GnssSateInfoList;

import org.greenrobot.eventbus.EventBus;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import geo.com.geosdk.GeoManage;
import geo.com.geosdk.listener.ConnectListener;
import geo.com.geosdk.listener.GeoLocationDataInterface;
import geo.com.geosdk.listener.GnssOutputDataListener;
import geo.com.geosdk.listener.PowerUpdateListener;
import geo.com.geosdkdemo.R;
import geo.com.geosdkdemo.bluetooth.BlueToothBroadcastReceiver;
import geo.com.geosdkdemo.bluetooth.BlueToothInit;
import geo.com.geosdkdemo.bluetooth.IBlueToothDeviceFoundListener;
import geo.com.geosdkdemo.bluetooth.IBondStateListener;
import geo.com.geosdkdemo.event.LocationUpdateEvent;
import geo.com.geosdkdemo.event.PowerBatteryLevelEvent;
import geo.com.geosdkdemo.util.SpUtils;
import geo.com.geosdkdemo.view.adapter.BlueToothDeviceAdapter;

import static android.view.View.VISIBLE;
import static geo.com.geosdkdemo.bluetooth.BlueToothInit.PERMISSIONS_REQUEST_CODE_ACCESS_COARSE_LOCATION;

public class CommunicationSetupActivity extends AppCompatActivity implements View.OnClickListener {
    private static final int MSG_CONNECT_SUCC = 1;
    private static final int MSG_CONNECT_DEFAIL = 2;
    private static final int MSG_DISCONNECT = 3;
    private static final int MSG_RECEIVE_DATA = 4;

    private Button btnConnectServer;
    private Button btnDisconnectServer;
    private Button btnSearchBlueTooth;
    private Button btnStopSearchBlueTooth;
    private Button btnGiveupConnect;
    private TextView tvCommonTitle;
    private TextView tvDeviceName;
    private ImageView ivCommonBack;
    private ListView listView;
    private ImageView ivLoading;
    private FrameLayout flLoading;
    private TextView tvLoading;

    private BlueToothInit operateBlueTooth;
    private Animation anim;
    private BlueToothDeviceAdapter adapter;
    private BluetoothAdapter mBtAdatper;
    private BlueToothBroadcastReceiver blueToothBroadcastReceiver;
    private BluetoothDevice device;
    public HashSet<BluetoothDevice> sets=new HashSet<>();
    public Set<BluetoothDevice> bondedDevices;
    public static final String LAST_DEVICE ="lastDevice";
    private MyHandler myHandler;
    private LocationManager locManager;



    class MyHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case MSG_CONNECT_SUCC:
                    whenConnectSucc();
                    break;
                case MSG_CONNECT_DEFAIL:
                    whenConnectDefail();
                    break;
                case MSG_DISCONNECT:
                    whenDisConnect();
                    break;
                case MSG_RECEIVE_DATA:
                    break;
            }
        }

        private void whenConnectDefail() {
            showToast("连接失败");
            btnSearchBlueTooth.setVisibility(VISIBLE);
            btnGiveupConnect.setVisibility(View.GONE);
            stopAnim();
        }

        private void whenDisConnect() {
            tvDeviceName.setText("无连接设备");
            btnConnectServer.setVisibility(VISIBLE);
            btnDisconnectServer.setVisibility(View.GONE);
            btnSearchBlueTooth.setVisibility(VISIBLE);
        }

        private void whenConnectSucc() {
            btnSearchBlueTooth.setVisibility(View.GONE);
            btnDisconnectServer.setVisibility(VISIBLE);
            btnConnectServer.setVisibility(View.GONE);
            btnGiveupConnect.setVisibility(View.GONE);
            stopAnim();
            if(device!=null){
                tvDeviceName.setText(device.getName());
                //保存最近一次连接成功的设备，给下次使用
                SpUtils.obtain().save(LAST_DEVICE, device.getAddress());
            }
            finish();

        }
    }


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment_equipment_communication_setup);
        initView();
        initListener();
        initData();
    }

    private void initData() {
        tvCommonTitle.setText("通讯设置");
        locManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
        myHandler=new MyHandler();
        //初始化蓝牙相关配置
        initBlueTooth();

        //判断蓝牙按钮是否打开--打开的话显示已经匹配过的蓝牙信息
        if(operateBlueTooth.isOpenBlueTooth()){
            whenOpenBlueTooth();
        }else{
            btnDisconnectServer.setVisibility(View.GONE);
        }

        //判断是不是连接状态--是的话显示连接状态
        if (GeoManage.getInstance().isConnectedBlueTooth()) {
            //是连接成功
            whenConnected();
        }

        //蓝牙配对状态监听
        blueToothBroadcastReceiver.setBlueToothBondListener(new IBondStateListener() {
            @Override
            public void bonded() {
                realStartConnect();
            }

            @Override
            public void bonding() {
                showToast("正在匹配");
            }

            @Override
            public void bondNone() {
                showToast("匹配失败");
                if (anim != null) {
                    stopAnim();
                    btnConnectServer.setEnabled(true);
                }
            }
        });

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                adapter.setCurrentItem(position);
                adapter.setmIsClick(true);
                adapter.notifyDataSetChanged();
                device = (BluetoothDevice) parent.getItemAtPosition(position);
            }
        });

        //关于连接的回调
        connectCallback();

        //关于定位信息的回调
        locationCallback();

        //电量回调
        powerBatteryLevelCallback();

    }

    private void powerBatteryLevelCallback() {
        //电池电量监听，每30s更新一次
        GeoManage.getInstance().setPowerUpdateListener(new PowerUpdateListener() {
            @Override
            public void onPowerUpdateListener() {
                EventBus.getDefault().postSticky(new PowerBatteryLevelEvent());
            }
        });

    }

    private void locationCallback() {
        //GNSS数据输出--定位信息、卫星信息、基站信息、RTK回复数据
        //GeoLocationDataInterface--包含GNSS相关数据
        GeoManage.getInstance().setGnssOutputDataListener(new GnssOutputDataListener() {
            @Override
            public void OnGnssLocationCallBack(GeoLocationDataInterface geoLocationDataInterface) {
                //有定位数据变化--通知更新定位信息相关UI界面
                EventBus.getDefault().postSticky(new LocationUpdateEvent(geoLocationDataInterface));
            }

            @Override
            public void OnGnssRefStationCallBack(GeoLocationDataInterface geoLocationDataInterface) {
                //有基站数据更新--基站相关数据
                GnssRefStationData gnssRefStationData = geoLocationDataInterface.getRefStationData();
            }

            @Override
            public void OnGnssSateInfoBack(GeoLocationDataInterface geoLocationDataInterface) {
                //有卫星信息更新--星图星表UI
                //具体使用如下：
                GnssSateInfoList sateInfoList = geoLocationDataInterface.getSateInfoList();
                for(int i=0;i<sateInfoList.getSateInfoList().size();i++){
                    GnssSateInfo gnssSateInfo=sateInfoList.getSateInfoList().get(i);
                    int type = gnssSateInfo.getType().swigValue();//type卫星类型
                    switch (type){
                        case 1://SATSYS_GPS
                            break;
                        case 2://SATSYS_GLONASS
                            break;
                        case 3://SATSYS_SBAS
                            break;
                        case 4://SATSYS_GALILEO
                            break;
                        case 5://SATSYS_BD
                            break;
                        case 6://SATSYS_QZSS
                            break;
                    }
                    //方位角
                    float azimuth = gnssSateInfo.getAzimuth();
                    //高度角
                    float elevation = gnssSateInfo.getElevation();
                    //卫星号
                    int prn = gnssSateInfo.getPrn();
                    //信噪比1
                    float snr1 = gnssSateInfo.getSnr1();
                }
            }

            @Override
            public void OnRtkRespondBack(String strGnssLine) {
                //自己发送的命令返回的@GNSS开头的数据
                Log.d("MainActivity", "OnRtkRespondBack: "+strGnssLine);
            }
        });
    }

    private void realStartConnect() {
        btnSearchBlueTooth.setVisibility(View.GONE);
        btnGiveupConnect.setVisibility(View.VISIBLE);
        //1.设置蓝牙地址--替换成自己的蓝牙地址
        String blueToothAdress=device.getAddress();
        GeoManage.getInstance().setBlueToothAddress(blueToothAdress);
        //2.开始启动连接
        GeoManage.getInstance().startConnectBlueTooth();
        //显示连接进度条
        startAnim("连接中");
    }

    private void connectCallback() {
        //1.连接成功失败的回调--此时在子线程中，不允许里面更新UI
        GeoManage.getInstance().setConnectListener(new ConnectListener() {
            @Override
            public void OnConnectCallBack(boolean bSucceed) {
                //是否连接成功---更新UI
                if(bSucceed){
                    //4.自动重连功能---手动断开和自动断开
                    //1.设置当前操作需不需要自动重连，区分自己断开连接和自动断开连接
                    //2.开始自动重连监听，更新UI，进行重新连接
                    GeoManage.getInstance().setAutoConnectBlueTooth(true);
                    myHandler.sendEmptyMessage(MSG_CONNECT_SUCC);
                }else{
                    GeoManage.getInstance().setAutoConnectBlueTooth(false);//没连接成功不进行自动重连，只有连接成功之后断开才进行自动重连
                    myHandler.sendEmptyMessage(MSG_CONNECT_DEFAIL);
                }
            }

            @Override
            public void OnDisConnectCallBack() {
                //连接成功后面中途断开---进行UI更新
                myHandler.sendEmptyMessage(MSG_DISCONNECT);
            }
        });
    }

    private void whenConnected() {
        btnSearchBlueTooth.setVisibility(View.GONE);
        btnConnectServer.setVisibility(View.GONE);
        btnDisconnectServer.setVisibility(VISIBLE);
        //当没有点击列表进行连接时，device代表的是上次保存的device
        if(device!=null){
            tvDeviceName.setText(device.getName());
        }
    }

    private void initBlueTooth() {
        mBtAdatper = BluetoothAdapter.getDefaultAdapter();
        adapter = new BlueToothDeviceAdapter(this, R.layout.layout_bluetooth_device_list_item);
        operateBlueTooth= new BlueToothInit(this,mBtAdatper, adapter);
        listView.setAdapter(adapter);
        registerBlueToothReceiver();
    }

    //当蓝牙打开时做的操作，打开的话列表中显示以匹配的蓝牙信息
    private void whenOpenBlueTooth() {
        String address= SpUtils.obtain().getString(LAST_DEVICE);
        //显示已配对的蓝牙item
        bondedDevices = mBtAdatper.getBondedDevices();
        Iterator<BluetoothDevice> iterator= bondedDevices.iterator();
        while(iterator.hasNext()){
            BluetoothDevice bluetoothDevice=iterator.next();
            if(bluetoothDevice.getAddress().equals(address)){
                device=bluetoothDevice;
            }
            adapter.add(bluetoothDevice);//因为适配器是ArrayAdapter
            adapter.notifyDataSetChanged();
        }
    }

    //注册蓝牙广播接受者
    public void registerBlueToothReceiver(){
        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothDevice.ACTION_FOUND);//找到设备
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//开始扫描
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索完成
        filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//状态改变--配对、未配对、正在配对
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);//蓝牙开启关闭
        filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);//信号强度
        blueToothBroadcastReceiver= BlueToothBroadcastReceiver.getSingleton();
        registerReceiver(blueToothBroadcastReceiver, filter);

        //搜索设备监听
        blueToothBroadcastReceiver.setBlueToothDeviceFoundListener(new IBlueToothDeviceFoundListener() {

            @Override
            public void onBlueToothDeviceFound(BluetoothDevice device, Intent intent) {
                if(sets.add(device)){//true表示元素添加成功，不是重复的数据
                    if(device.getName()!=null && device.getAddress()!=null){
                        adapter.add(device);//因为适配器是ArrayAdapter
                        adapter.notifyDataSetChanged();
                    }
                }
            }
            @Override
            public void onBlueToothSearching() {

                btnSearchBlueTooth.setVisibility(View.GONE);
                btnStopSearchBlueTooth.setVisibility(VISIBLE);
                startAnim("搜索中");
            }

            @Override
            public void onBlueToothSearched() {
                btnStopSearchBlueTooth.setVisibility(View.GONE);
                if (anim != null) {
                    btnSearchBlueTooth.setVisibility(VISIBLE);
                    btnConnectServer.setEnabled(true);
                    stopAnim();
                }
            }
        });
    }


    private void startAnim(String str) {
        anim = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.anim_round_rotate);
        LinearInterpolator interpolator = new LinearInterpolator();  //设置匀速旋转，在xml文件中设置会出现卡顿
        anim.setInterpolator(interpolator);
        if (anim != null) {
            btnConnectServer.setEnabled(false);
            tvLoading.setText(str);
            flLoading.setVisibility(VISIBLE);
            ivLoading.startAnimation(anim);  //开始动画
        }
    }

    //停止动画
    private void stopAnim() {
        if (anim != null) {
            anim =null;
            btnConnectServer.setEnabled(true);
            flLoading.setVisibility(View.GONE);
            ivLoading.clearAnimation();
        }
    }


    @Override
    public void onClick(View v) {
        if(v==ivCommonBack){
            finish();
        }else if(v== btnConnectServer){
            onClickConnect();
        }else if(v== btnGiveupConnect){
            onClickGiveUpConnect();
        }else if(v== btnDisconnectServer){
            onClickDisConnect();
        }else if ( v == btnSearchBlueTooth) {
            if(operateBlueTooth.requestPermission()){
                onClickSearchBlueTooth();
            }
        } else if ( v == btnStopSearchBlueTooth) {
            operateBlueTooth.stopSearchBlueTooth();
        }
    }

    private void onClickGiveUpConnect() {
        btnSearchBlueTooth.setVisibility(VISIBLE);
        btnGiveupConnect.setVisibility(View.GONE);
        stopAnim();
        GeoManage.getInstance().disConnectBlueTooth();
    }

    private void onClickConnect() {
        if(flLoading.getVisibility()==VISIBLE)
            return;
        connectToServer();
    }

    private void onClickDisConnect() {
        GeoManage.getInstance().setAutoConnectBlueTooth(false);//表示不需要自动重连,手动断开的
        GeoManage.getInstance().disConnectBlueTooth();
    }

    //连接服务器
    public void connectToServer(){
        if (!mBtAdatper.isEnabled()) {
            showToast("请先打开蓝牙");
            return;
        }
        if(device!=null){
            //开始配对
            if(operateBlueTooth.getBondState(device)){//已经成功匹配过，直接开始显示连接对话框
                //开始进行连接
                realStartConnect();
            }

        }else{
            showToast("请选择需要连接的设备!");
        }
    }

    public void onClickSearchBlueTooth(){
        //判断系统是不是关闭了系统的位置服务
        if(!locManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
            // 未打开位置开关，提示用户或做相应处理
            showToast("请打开系统位置服务，否则无法搜索蓝牙！");
            return;
        }
        if(adapter!=null){
            adapter.setCurrentItem(-1);
            adapter.setmIsClick(false);
            adapter.notifyDataSetChanged();
        }
        if(sets!=null && adapter!=null){
            adapter.clear();
            sets.clear();
        }
        operateBlueTooth.searchBlueTooth();
    }

    //6.0以上搜索蓝牙需要定位权限或者无法搜索定位权限回调
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if(requestCode==PERMISSIONS_REQUEST_CODE_ACCESS_COARSE_LOCATION){
                int nLengthP=permissions.length;
                if (nLengthP >0) {
                    boolean bAllGranted=true;
                    //权限是否全部通过允许
                    for(int result:grantResults) {
                        if(result != PackageManager.PERMISSION_GRANTED) {
                            bAllGranted = false;
                            break;
                        }
                    }

                    if (bAllGranted) {
                        onClickSearchBlueTooth();
                    } else {
                        showToast("请允许APP获取位置权限和读写文件权限，否则无法使用APP");
                    }
                }
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    public void showToast(String str) {
        Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
    }

    private void initView() {
        ivCommonBack=findViewById(R.id.iv_common_back);
        tvCommonTitle=findViewById(R.id.tv_common_title);
        tvDeviceName=findViewById(R.id.tv_device_name);
        btnDisconnectServer = findViewById(R.id.btn_disconnect);
        btnConnectServer = findViewById(R.id.btn_connect);
        btnSearchBlueTooth = findViewById(R.id.btn_search);
        btnStopSearchBlueTooth = findViewById(R.id.btn_stop_search);
        btnGiveupConnect = findViewById(R.id.btn_giveup_connect);
        listView =  findViewById(R.id.listView);
        ivLoading = findViewById(R.id.iv_loading);
        tvLoading = findViewById(R.id.tv_loading_title);
        flLoading = findViewById(R.id.fl_loading);
    }

    protected void initListener() {
        btnSearchBlueTooth.setOnClickListener(this);
        btnStopSearchBlueTooth.setOnClickListener(this);
        btnConnectServer.setOnClickListener(this);
        btnDisconnectServer.setOnClickListener(this);
        ivCommonBack.setOnClickListener(this);
        btnGiveupConnect.setOnClickListener(this);
    }

    @Override
    public void onDestroy() {
        if(operateBlueTooth!=null){
            operateBlueTooth.stopSearchBlueTooth();
        }
        stopAnim();
        unregisterReceiver(blueToothBroadcastReceiver);
        super.onDestroy();
    }
}
